package com.blue.wechat.invoke;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.blue.core.dict.WechatMediaType;
import com.blue.core.util.ExceptionUtil;
import com.blue.core.util.JsonUtil;
import com.blue.wechat.invoke.model.ErrorMsg;
import com.blue.wechat.invoke.model.InvokeResult;
import com.blue.wechat.invoke.model.Json;

/**
 * 微信调用接口工具类
 * 
 * @author zhengj
 * @since 1.0 2016年11月30日
 */
public class WechatInvokeUtil
{
	private static Logger logger = LoggerFactory.getLogger(WechatInvokeUtil.class);
	private static Pattern filename = Pattern.compile("filename=\"(.+)\"");
	
	private WechatInvokeUtil()
	{
	}
	
	/**
	 * 获取微信素材类型
	 * 
	 * @param entity
	 * @param response
	 * @return
	 */
	public static WechatMediaType geMediaType(HttpEntity entity, CloseableHttpResponse response)
	{
		WechatMediaType type = null;
		if (entity != null)
		{
			Header header = entity.getContentType();
			if (header != null)
			{
				int pos = header.getValue().indexOf(';');
				String mimeType = (pos == -1 ? header.getValue() : header.getValue().substring(0, pos));
				if (mimeType.startsWith("image"))
					type = WechatMediaType.IMAGE;
				else if (mimeType.startsWith("audio"))
					type = WechatMediaType.VOICE;
			}
		}
		if (type == null && response != null)
		{
			Header header = response.getFirstHeader("Content-disposition");
			if (header != null)
			{
				//System.out.println(header.getValue());
				Matcher m = filename.matcher(header.getValue());
				if (m.find())
				{
					String file = m.group(1);
					if (file != null && !file.isEmpty())
					{
						file = file.toLowerCase();
						if (file.endsWith(".jpg") || file.endsWith(".jpeg") || file.endsWith(".png") || file.endsWith(".gif"))
							type = WechatMediaType.IMAGE;
						else if (file.endsWith(".amr") || file.endsWith(".mp3"))
							type = WechatMediaType.VOICE;
					}
				}
			}
		}
		return type;
	}
	
	/**
	 * 对象 ==> String
	 * 
	 * @param object 对象
	 * @return String
	 */
	public static String toString(Object object)
	{
		if (object == null)
			return null;
		
		if (object instanceof Json)
			return ((Json)object).toJson();
		else if (object instanceof CharSequence)
			return object.toString();
		else
			return JsonUtil.output(object);
	}
	
	/**
	 * 微信接口调用日志
	 * 
	 * @param wechat 微信公众号名称
	 * @param service 微信接口名称
	 * @param url 微信接口URL
	 * @param get 接口调用GET参数
	 * @param post 接口调用POST参数
	 * @param used 接口调用用时，毫秒
	 * @param resp 接口返回内容
	 * @param e 接口抛出异常
	 */
	public static void log(String wechat, String service, String url, String get, Object post, Integer used, String resp, Exception e)
	{
		String strPost = toString(post);
		
		if (e == null) // 调用成功
		{
			logger.info("微信号：{}，接口：{}，GET参数：{}，POST参数：{}，用时：{} ms，状态：成功\nURL：{}\n返回：{}",
					wechat, service, get, strPost, used, url, resp);
		}
		else // 调用失败
		{
			logger.error("微信号：{}，接口：{}，GET参数：{}，POST参数：{}，用时：{} ms，状态：失败\nURL：{}\n返回：{}\n异常：{}",
					wechat, service, get, strPost, used, url, resp, ExceptionUtil.exceptionToString(e, 20));
		}
	}
	
	/**
	 * 把响应json文件转化为对象
	 * 
	 * @param <T> 类型参数
	 * @param resp HTTP响应文本
	 * @param clazz 类
	 * @return 响应对象
	 */
	public static <T> InvokeResult<T> toObject(String resp, Class<T> clazz)
	{
		InvokeResult<T> result = new InvokeResult<T>();
		if (resp.contains("\"errcode\":"))
		{
			ErrorMsg error = JSON.parseObject(resp, ErrorMsg.class);

			result.setError(error);
			if ("0".equals(error.getErrcode()))
			{
				T obj = JSON.parseObject(resp, clazz);
				
				result.setResult(true);
				result.setSuccess(obj);
			}
			else
			{
				result.setResult(false);
			}
		}
		else
		{
			T obj = JSON.parseObject(resp, clazz);
			
			result.setResult(true);
			result.setSuccess(obj);
		}
			
		
		return result;
	}
	
	/**
	 * 把响应json文件转化为对象
	 * 
	 * @param resp HTTP响应文本
	 * @param clazz 类
	 * @return 响应对象
	 */
	public static <T> T toResponse(String resp, Class<T> clazz)
	{
		T obj = null;
		if (resp.contains("\"errcode\":"))
		{
			ErrorMsg error = JSON.parseObject(resp, ErrorMsg.class);
			if (!"0".equals(error.getErrcode()))
				throw InvokeException.getException(InvokeException.ERROR + error.getErrmsg());
			
			obj = JSON.parseObject(resp, clazz);
		}
		else
		{
			obj = JSON.parseObject(resp, clazz);
		}
		return obj;
	}
	
}
